home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Medal Software 3
/
Gold Medal Software - Volume 3 (Gold Medal) (1994).iso
/
bbsutils
/
smb_110a.arj
/
MAIL2SMB.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-03-28
|
8KB
|
308 lines
/* MAIL2SMB.C */
/* Converts Synchronet Version 1 (proprietary) e-mail to SMB format */
/* The intention of this source code is an example of how to use the SMBLIB */
/* library functions to access an SMB format message base. */
/* This program and source code are freeware. May be used in part or whole */
/* for any purpose without consent or notification of Digital Dynamics. */
/* Digital Dynamics does request that developers that release products that */
/* support the SMB format notify Digital Dynamics so the implementation */
/* and contact chapters in the technical specification may be updated. */
#include "smblib.h"
#include "crc32.h"
#include <dos.h>
char sbbs[128];
/****************************************************************************/
/* Updates 16-bit "rcrc" with character 'ch' */
/****************************************************************************/
void ucrc16(uchar ch, ushort *rcrc) {
ushort i, cy;
uchar nch=ch;
for (i=0; i<8; i++) {
cy=*rcrc & 0x8000;
*rcrc<<=1;
if (nch & 0x80) *rcrc |= 1;
nch<<=1;
if (cy) *rcrc ^= 0x1021; }
}
/****************************************************************************/
/* Returns 16-crc of string (not counting terminating NULL) */
/****************************************************************************/
ushort crc16(char *str)
{
int i=0;
ushort crc=0;
ucrc16(0,&crc);
while(str[i])
ucrc16(str[i++],&crc);
ucrc16(0,&crc);
ucrc16(0,&crc);
return(crc);
}
/****************************************************************************/
/* Truncates white-space chars off end of 'str' and terminates at first tab */
/****************************************************************************/
void truncsp(char *str)
{
char c;
str[strcspn(str,"\t")]=0;
c=strlen(str);
while(c && (uchar)str[c-1]<=' ') c--;
str[c]=0;
}
/****************************************************************************/
/* Converts an ASCII Hex string into an ulong */
/****************************************************************************/
ulong ahtoul(char *str)
{
ulong l,val=0;
while((l=(*str++)|0x20)!=0x20)
val=(l&0xf)+(l>>6&1)*9+val*16;
return(val);
}
ulong hexplus(char *str)
{
int i=0;
if(toupper(str[0])>'F') {
i=toupper(str[0])-'F';
str[0]='f'; }
return(ahtoul(str)+(i*0x100));
}
/****************************************************************************/
/* Returns the length of the file in 'filespec' */
/****************************************************************************/
long flength(char *filespec)
{
struct ffblk f;
if(findfirst(filespec,&f,0)==0)
return(f.ff_fsize);
return(-1L);
}
long fdate(char *filespec)
{
struct ffblk f;
struct date fd;
struct time ft;
if(findfirst(filespec,&f,0)==NULL) {
fd.da_day=f.ff_fdate&31;
fd.da_mon=(f.ff_fdate>>5)&15;
fd.da_year=1980+((f.ff_fdate>>9)&127);
ft.ti_hour=(f.ff_ftime>>11)&31;
ft.ti_min=(f.ff_ftime>>5)&63;
ft.ti_sec=0;
return(dostounix(&fd,&ft)); }
else return(NULL);
}
/****************************************************************************/
/* Returns the FidoNet address kept in str as ASCII. */
/****************************************************************************/
fidoaddr_t atofaddr(char *str)
{
char *p;
fidoaddr_t addr;
addr.zone=addr.net=addr.node=addr.point=0;
if((p=strchr(str,':'))!=NULL) {
addr.zone=atoi(str);
addr.net=atoi(p+1); }
else {
addr.zone=1;
addr.net=atoi(str); }
if(!addr.zone) /* no such thing as zone 0 */
addr.zone=1;
if((p=strchr(str,'/'))!=NULL)
addr.node=atoi(p+1);
else {
addr.net=1;
addr.node=atoi(str); }
if((p=strchr(str,'.'))!=NULL)
addr.point=atoi(p+1);
return(addr);
}
int main(void)
{
uchar *p,str[128],from[128],to[128],subj[128],fname[128]
,buf[SDT_BLOCK_LEN];
ushort ftype,flen,xlat;
ushort i,j,k,msgs,net,x;
ulong length,crc;
FILE *ixt,*stream;
smbmsg_t msg;
smbstatus_t status;
fidoaddr_t faddr;
p=getenv("SBBS");
if(!p) {
printf("SBBS environment variable must be set.\r\n");
printf("example: SET SBBS=C:\\SBBS\r\n");
exit(1); }
strcpy(sbbs,p);
strupr(sbbs);
strcpy(smb_file,"MAIL");
smb_open(10);
sprintf(str,"%s\\INDX\\MAIL.IXT",sbbs);
if((ixt=fopen(str,"rb"))==NULL) {
printf("error opening %s\r\n",str);
exit(1); }
if(!filelength(fileno(shd_fp)))
smb_create(0,2000,0,10);
smb_getstatus(&status); // Initialized for first call to smb_addcrc()
for(i=0;!feof(ixt);i++) {
memset(&msg,0,sizeof(smbmsg_t));
memcpy(msg.hdr.id,"SHD\x1a",4);
msg.hdr.version=SMB_VERSION;
if(!fgets(str,81,ixt))
break;
printf("%4u\r",i+1);
str[8]-=SP;
if(str[8]&(1<<1))
msg.idx.attr|=MSG_ANONYMOUS;
if(str[8]&16)
msg.hdr.auxattr|=MSG_FILEATTACH;
if(str[17]==SP)
msg.idx.attr|=MSG_READ;
msg.hdr.attr=msg.idx.attr;
str[8]=0;
strcpy(fname,str);
str[17]=0;
net=NET_NONE;
msg.hdr.when_written.time=ahtoul(str+9);
strcpy(from,str+18);
truncsp(from);
p=strrchr(from,'@');
if(p) {
*p=0;
truncsp(from);
p++;
net=NET_FIDO;
smb_hfield(&msg,SENDERNETTYPE,sizeof(ushort),&net);
faddr=atofaddr(p);
smb_hfield(&msg,SENDERNETADDR,sizeof(fidoaddr_t),&faddr); }
smb_hfield(&msg,SENDER,strlen(from),from);
sprintf(str,"%.3s",fname+3);
j=hexplus(str);
if(j) {
sprintf(from,"%u",j);
msg.idx.from=atoi(from);
smb_hfield(&msg,SENDEREXT,strlen(from),from); }
else
msg.idx.from=0;
if(!fgets(to,81,ixt))
break;
truncsp(to);
smb_hfield(&msg,RECIPIENT,strlen(to),to);
sprintf(str,"%.3s",fname);
sprintf(to,"%lu",hexplus(str));
smb_hfield(&msg,RECIPIENTEXT,strlen(to),to);
msg.idx.to=atoi(to);
if(!fgets(subj,81,ixt))
break;
truncsp(subj);
smb_hfield(&msg,SUBJECT,strlen(subj),subj);
strlwr(subj);
msg.idx.subj=crc16(subj);
sprintf(str,"%s\\DATA\\MAIL\\%s.MSG",sbbs,fname);
length=flength(str);
msg.hdr.when_imported.time=fdate(str);
if(length<1L) {
printf("invalid length (%ld) for %s\n",length,str);
exit(1); }
if((stream=fopen(str,"rb"))==NULL) {
printf("\nError opening %s for read\n",str);
smb_freemsgmem(msg);
continue; }
fgets(str,81,stream);
length-=strlen(str);
fgets(str,81,stream);
length-=strlen(str);
fgets(str,81,stream);
length-=strlen(str);
fgets(str,81,stream);
length-=strlen(str);
length+=2; /* for translation string */
if(smb_open_da(10)) {
printf("error opening %s.SDA\n",smb_file);
exit(1); }
msg.hdr.offset=smb_fallocdat(length,1);
fclose(sda_fp);
if(msg.hdr.offset && msg.hdr.offset<1L) {
printf("error %ld allocating blocks\r\n",msg.hdr.offset);
exit(1); }
fseek(sdt_fp,msg.hdr.offset,SEEK_SET);
xlat=XLAT_NONE;
fwrite(&xlat,2,1,sdt_fp);
crc=0xffffffffUL;
x=SDT_BLOCK_LEN-2;
while(!feof(stream)) {
memset(buf,NULL,x);
k=fread(buf,1,x,stream);
while(k && !buf[k-1]) k--; /* take off NULLs, if any */
if((feof(stream) || k!=x) && buf[k-1]==LF && buf[k-2]==CR)
k-=2;
for(j=0;j<k;j++)
crc=ucrc32(buf[j],crc);
fwrite(buf,k,1,sdt_fp);
x=SDT_BLOCK_LEN; }
fclose(stream);
crc=~crc;
j=smb_addcrc(status.max_crcs,crc,10);
if(j) {
if(j==1) {
printf("\nDuplicate message\n");
smb_freemsgmem(msg);
continue; }
printf("smb_addcrc returned %d\n",j);
exit(1); }
smb_dfield(&msg,TEXT_BODY,length);
smb_addmsghdr(&msg,&status,1,10);
smb_freemsgmem(msg); }
return(0);
}